import axios from 'axios';

import Config from '../../config';
import getAPIHeaders from '../get-api-headers';
import Disbursement from './disbursement';
import DisbursementType from './disbursement-type';

export interface SlpFee {
    withdraw_fee: string;
    minimum_slp: string;
}

export default class DisbursementManager {
    static save = async (disbursement: Disbursement): Promise<Disbursement> => {
        const data = {
            title: disbursement.title,
            total: disbursement.total,
            currency: disbursement.currency,
            network: disbursement.network,
            type: disbursement.type,
        };

        const call = await axios.post(Config.getAPI() + '/disbursement/save', data, {
            headers: await getAPIHeaders(),
        });

        if (call.data['disbursement']) {
            return Disbursement.fromJSON(call.data['disbursement']);
        }

        return null;
    };

    static getAll = async (): Promise<Array<{}>> => {
        const call = await axios.get(Config.getAPI() + '/disbursement/all', {
            headers: await getAPIHeaders(),
        });
        return call.data['disbursements'];
    };

    static getActive = async (): Promise<Array<Disbursement>> => {
        const call = await axios.get(Config.getAPI() + '/disbursement/active', {
            headers: await getAPIHeaders(),
        });

        if (call.data['disbursements']) {
            const disbursements = new Array<Disbursement>();

            for (let i = 0; i < call.data['disbursements'].length; i++) {
                disbursements.push(Disbursement.fromJSON(call.data['disbursements'][i]));
            }

            return disbursements;
        }

        return null;
    };

    static getByPage = async (
        page = 0
    ): Promise<{
        hasMore: boolean;
        disbursements: Array<{}>;
    }> => {
        const call = await axios.get(Config.getAPI() + `/disbursement/all?page=${page}`, {
            headers: await getAPIHeaders(),
        });

        if (call.data?.error) {
            throw call.data.error;
        }

        const result = {
            disbursements: [],
            hasMore: false,
        };

        if (call.data && call.data.disbursements) {
            const { disbursements } = call.data;

            result.disbursements = disbursements;
            result.hasMore = !call.data.no_more_results;
        }

        return result;
    };

    static getAllPage = async (page?: number, curr = []): Promise<any[]> => {
        if (!page) {
            page = 0;
        }

        try {
            const { disbursements, hasMore } = await DisbursementManager.getByPage(page);

            curr = [...curr, ...disbursements];
            if (hasMore) {
                curr = await DisbursementManager.getAllPage(page + 1, curr);
            }
        } catch (exception) {
            console.log(exception);
        }

        return curr;
    };

    static getProgress = async (disbursementID: number): Promise<Disbursement> => {
        try {
            const call = await axios.get(
                Config.getAPI() + '/disbursement/progress?disbursement_id=' + disbursementID,
                {
                    headers: await getAPIHeaders(),
                }
            );

            if (call.data['disbursement']) {
                return Disbursement.fromJSON(call.data['disbursement']);
            }
        } catch (exception) {}

        return null;
    };

    static getSlpFee = async (): Promise<SlpFee> => {
        try {
            const call = await axios.get(Config.getAPI() + '/disbursement/slp-fee', {
                headers: await getAPIHeaders(),
            });

            return call.data;
        } catch (exception) {}
        return null;
    };

    static getTypes = async (): Promise<Array<DisbursementType>> => {
        const call = await axios.get(`${Config.getAPI()}/disbursement/types`, {
            headers: await getAPIHeaders(),
        });

        if (call.data['types']) {
            const types = new Array<DisbursementType>();

            for (let i = 0; i < call.data['types'].length; i++) {
                types.push(DisbursementType.fromJSON(call.data['types'][i]));
            }

            return types;
        }

        return null;
    };
}
